#pragma once

#include <iostream>
#include <string>
#include <cstdio>
#include <stdarg.h>
#include <unistd.h>
#include <ctime>
#include <sys/types.h>

std::string filename = "TCP_server.log";

enum
{
    Bug = 1,
    Info,
    Warring,
    Error,
    Fatal
};

static std::string To_LevelStr(int level)
{
    switch (level)
    {
    case Bug:
        return "Bug";
    case Info:
        return "Info";
    case Warring:
        return "Warring";
    case Error:
        return "Error";
    case Fatal:
        return "Fatal";
    }
}

static std::string GetTime()
{
    time_t cur = time(nullptr);
    struct tm *tmp = localtime(&cur);
    char buffer[1024];
    snprintf(buffer, sizeof(buffer), "%d-%d-%d %d:%d:%d", tmp->tm_year + 1900, tmp->tm_mon + 1,
             tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec);

    return std::string(buffer);
}

// 日志格式：日志等级 时间 pid 消息体
void LogMessage(int level, const char *format, ...) 
{
    // 在OS可变参数中的存储方式，类似于栈，数据一直往后压栈
    // 而format就是指向参数的首位
    char logLeft[1024]; // 左半部分：日志等级 时间 pid
    std::string level_str = To_LevelStr(level);
    std::string time_str = GetTime();
    snprintf(logLeft, sizeof(logLeft), "[%s] [%s] [%d] ", level_str.c_str(), time_str.c_str(), getpid());

    char logRight[1024]; // 右半部分：消息体
    va_list p; // 本质是 char*
    va_start(p, format); // p 指向可变参数的起始位置
    vsnprintf(logRight, sizeof(logRight), format, p); // [缓冲区, 缓冲区大小, 格式控制, 可变参数列表]
    va_end(p); // p = NULL

    printf("%s%s\n", logLeft, logRight);
    // FILE* fp = fopen(filename.c_str(), "a");
    // fprintf(fp, "%s%s\n", logLeft, logRight);
    // fclose(fp);
}